package com.joven.shelltest.utils.clearandreloadcache;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Set;

/**
 * 延时双删切面
 * @Author wzj
 * @Date 2023-11-07 14:23
 **/
@Aspect
@Component
public class ClearAndReloadCacheAspect {
    @Autowired
    private RedisTemplate redisTemplate;

    @Pointcut("@annotation(com.joven.shelltest.utils.clearandreloadcache.ClearAndReloadCache)")
    public void pointCut(){
    }

    @Around("pointCut()")
    public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
        System.out.println("----------- 环绕通知 -----------");
        System.out.println("环绕通知的目标方法名：" + proceedingJoinPoint.getSignature().getName());

        Signature signature1 = proceedingJoinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature)signature1;
        //方法对象
        Method targetMethod = methodSignature.getMethod();
        //反射得到自定义注解的方法对象
        ClearAndReloadCache annotation = targetMethod.getAnnotation(ClearAndReloadCache.class);
        //获取自定义注解的方法对象的参数即name
        String name = annotation.name();
        Set<String> keys = redisTemplate.keys("*" + name + "*");
        redisTemplate.delete(keys);

        //执行加入双删注解的改动数据库的业务
        Object proceed = null;
        try {
            proceed = proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        //开一个线程 延迟1秒（此处是1秒举例，可以改成自己的业务）
        // 在线程中延迟删除  同时将业务代码的结果返回 这样不影响业务代码的执行
        new Thread(() -> {
            try {
                Thread.sleep(1000);
                Set<String> keys1 = redisTemplate.keys("*" + name + "*");//模糊删除
                redisTemplate.delete(keys1);
                System.out.println("-----------1秒钟后，在线程中延迟删除完毕 -----------");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        //返回业务代码的值
        return proceed;
    }
}
